from flask import Blueprint, session, redirect, url_for, render_template, request, jsonify
from flask_login import current_user, login_user, login_required, logout_user
from flask_mail import Message
from applications.extensions import flask_mail as mail, db
from applications.common.admin import get_captcha, login_log
from applications.common.utils.http import fail_api, success_api
from applications.models import User, Role
from applications.models.admin_power import Power
import random
import string
from datetime import datetime, timedelta
from werkzeug.security import generate_password_hash

bp = Blueprint('passport', __name__, url_prefix='/passport')

# 存储验证码的字典
email_codes = {}

# 生成随机验证码
def generate_code(length=6):
    return ''.join(random.choices(string.digits, k=length))

# 发送邮件验证码
def send_email_code(email, code):
    try:
        msg = Message(
            subject='验证码',
            recipients=[email],
            body=f'您的验证码是：{code}，有效期为5分钟。',
            charset='utf-8'
        )
        mail.send(msg)
        return True
    except Exception as e:
        print(f"发送邮件失败: {str(e)}")
        return False

# 验证邮箱验证码
def verify_email_code(email, code):
    code_info = email_codes.get(email)
    if not code_info or datetime.now() > code_info['expire_time']:
        return False
    if code != code_info['code']:
        return False
    return True

# 获取验证码
@bp.get('/getCaptcha')
def captcha():
    resp, code = get_captcha()
    session["code"] = code
    return resp


# 登录
@bp.get('/login')
def login():
    if current_user.is_authenticated:
        return redirect(url_for('index.index'))
    return render_template('system/login.html')


# 登录
@bp.post('/login')
def login_post():
    req = request.form
    username = req.get('username')
    password = req.get('password')
    remember = bool(req.get('remember-me'))
    code = req.get('captcha').__str__().lower()

    if not username or not password or not code:
        return fail_api(msg="用户名或密码没有输入")
    s_code = session.get("code", None)
    session["code"] = None

    if not all([code, s_code]):
        return fail_api(msg="参数错误")

    if code != s_code:
        return fail_api(msg="验证码错误")
    user = User.query.filter_by(username=username).first()

    if not user:
        return fail_api(msg="不存在的用户")

    if user.enable == 0:
        return fail_api(msg="用户被暂停使用")

    if username == user.username and user.validate_password(password):
        # 登录
        login_user(user, remember=remember)
        # 记录登录日志
        login_log(request, uid=user.id, is_access=True)
        # 授权路由存入session
        role = current_user.role
        user_power = []
        for i in role:
            if i.enable == 0:
                continue
            for p in i.power:
                if p.enable == 0:
                    continue
                user_power.append(p.code)
        session['permissions'] = user_power
        # # 角色存入session
        # roles = []
        # for role in current_user.role.all():
        #     roles.append(role.id)
        # session['role'] = [roles]

        return success_api(msg="登录成功")

    login_log(request, uid=user.id, is_access=False)
    return fail_api(msg="用户名或密码错误")


# 忘记密码页面
@bp.get('/forget')
def forget():
    if current_user.is_authenticated:
        return redirect(url_for('index.index'))
    return render_template('system/forget.html')


# 发送重置密码验证码
@bp.post('/send_reset_code')
def send_reset_code():
    email = request.form.get('email')
    if not email:
        return jsonify({'success': False, 'msg': '请输入邮箱'})
    
    user = User.query.filter_by(email=email).first()
    if not user:
        return jsonify({'success': False, 'msg': '该邮箱未注册'})
    
    code = generate_code()
    if send_email_code(email, code):
        email_codes[email] = {
            'code': code,
            'expire_time': datetime.now() + timedelta(minutes=5)
        }
        return jsonify({'success': True, 'msg': '验证码已发送'})
    return jsonify({'success': False, 'msg': '发送验证码失败'})


# 重置密码
@bp.post('/reset_password')
def reset_password():
    try:
        data = request.form
        email = data.get('email')
        email_code = data.get('emailCode')
        new_password = data.get('newPassword')
        confirm_password = data.get('confirmPassword')
        
        if not all([email, email_code, new_password, confirm_password]):
            return jsonify({'success': False, 'msg': '请填写完整信息'})
        
        if new_password != confirm_password:
            return jsonify({'success': False, 'msg': '两次输入的密码不一致'})
        
        # 验证邮箱验证码
        if not verify_email_code(email, email_code):
            return jsonify({'success': False, 'msg': '验证码错误或已过期'})
        
        # 查找用户
        user = User.query.filter_by(email=email).first()
        if not user:
            return jsonify({'success': False, 'msg': '用户不存在'})
        
        # 更新密码
        user.password_hash = generate_password_hash(new_password)
        db.session.commit()
        
        # 删除已使用的验证码
        email_codes.pop(email)
        
        return jsonify({'success': True, 'msg': '密码重置成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'msg': str(e)})


# 发送注册验证码
@bp.post('/send_register_code')
def send_register_code():
    email = request.form.get('email')
    if not email:
        return fail_api(msg="请输入邮箱")
    
    user = User.query.filter_by(email=email).first()
    if user:
        return fail_api(msg="该邮箱已被注册")
    
    code = generate_code()
    if send_email_code(email, code):
        email_codes[email] = {
            'code': code,
            'expire_time': datetime.now() + timedelta(minutes=5)
        }
        return success_api(msg="验证码已发送")
    return fail_api(msg="发送验证码失败")


# 注册页面
@bp.get('/register')
def register():
    if current_user.is_authenticated:
        return redirect(url_for('index.index'))
    return render_template('system/register.html')


# 注册账号
@bp.route('/register', methods=['POST'])
def register_post():
    try:
        data = request.form
        username = data.get('username')
        password = data.get('password')
        email = data.get('email')
        email_code = data.get('emailCode')
        
        # 验证邮箱验证码
        if not verify_email_code(email, email_code):
            return jsonify({'success': False, 'msg': '验证码错误或已过期'})
            
        # 检查用户名是否已存在
        if User.query.filter_by(username=username).first():
            return jsonify({'success': False, 'msg': '用户名已存在'})
            
        # 检查邮箱是否已存在
        if User.query.filter_by(email=email).first():
            return jsonify({'success': False, 'msg': '邮箱已被注册'})
            
        # 创建新用户
        user = User(
            username=username,
            password_hash=generate_password_hash(password),
            email=email,
            enable=1
        )
        
        # 获取普通用户角色
        common_role = Role.query.filter_by(id=2).first()
        if not common_role:
            return jsonify({'success': False, 'msg': '系统错误：普通用户角色不存在'})
            
        # 确保普通用户角色拥有module:lstm权限
        model_predict_power = Power.query.filter_by(code='module:lstm').first()
        if model_predict_power and model_predict_power not in common_role.power:
            common_role.power.append(model_predict_power)
            db.session.commit()
            
        # 分配角色
        user.role.append(common_role)
        
        # 保存用户
        db.session.add(user)
        db.session.commit()
        
        # 删除已使用的验证码
        email_codes.pop(email)
        
        return jsonify({'success': True, 'msg': '注册成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'msg': str(e)})


# 退出登录
@bp.post('/logout')
@login_required
def logout():
    logout_user()

    if 'permissions' in session:
        session.pop('permissions')

    return success_api(msg="注销成功")
